#ifndef _Qing_QUEUE_HPP_
#define _Qing_QUEUE_HPP_

#include<iostream>
#include<vector>
#include<pthread.h>
#include"Sem.hpp"

const int g_defualt_num=5;

template<class T>
class RingQueue
{
public:
    RingQueue(int defualt_num=g_defualt_num)
    :rq_(defualt_num),num_(defualt_num),
    c_step(0),p_step(0),
    space_sem_(defualt_num),data_sem_(0)
    {
        pthread_mutex_init(&clock,nullptr);
        pthread_mutex_init(&plock,nullptr);
    }
    ~RingQueue()
    {
        pthread_mutex_destroy(&clock);
        pthread_mutex_destroy(&plock);
    }
    void Push(const T& in)
    {
        //先申请信号量
        space_sem_.p();
        pthread_mutex_lock(&plock);
        //竞争成功的线程进入
        rq_[p_step++]=in;
        p_step%=num_;
        pthread_mutex_unlock(&plock);
        data_sem_.v();
    }
    void Pop(T* out)
    {
        data_sem_.p();
        pthread_mutex_lock(&clock);
        *out=rq_[c_step++];
        c_step%=num_;
        pthread_mutex_unlock(&clock);
        space_sem_.v();
    }
private:
    std::vector<T>rq_;
    int num_;
    int c_step;//消费下标
    int p_step;//生产下标
    Sem space_sem_;//空间信号量
    Sem data_sem_;//资源信号量
    pthread_mutex_t clock;
    pthread_mutex_t plock;
};
#endif